import 'package:event_bus/event_bus.dart';
import 'package:flutter/cupertino.dart';
import 'package:shimo_app/bus/protocol/protocol.dart';
import 'package:shimo_app/bus/struct/error.dart';
import 'package:shimo_app/bus/struct/log.dart';

import '../frame/frame.dart';
import '../frame/parse.dart';
import '../struct/boardStatus.dart';
import '../struct/message.dart';
import '../struct/request_id.dart';
import '../struct/task_progress.dart';

/// 轮询协议处理器
/// 负责处理设备状态轮询相关的消息接收和事件分发
class Poll extends Protocol {
  /// 事件总线，用于发布各种状态事件
  EventBus eventbus;

  /// 构造函数，初始化事件总线
  Poll(this.eventbus);

  /// 处理异步消息
  /// 对于轮询协议，异步消息直接标记为已完成
  @override
  AsyncResult handleAsyncMessage(MessageBean message) {
    return AsyncResult.DONE;
  }

  /// 处理同步回复消息
  /// 解析帧数据并分发不同类型的事件到事件总线
  /// [reply] 接收到的回复帧
  /// 返回 true 表示处理成功
  @override
  bool handleSyncReply(Frame reply) {
    // 循环解析帧中的所有消息
    while (true) {
      // 解析消息
      final msg = Parse.parseMessage(reply);

      // 如果没有更多消息，退出循环
      if (msg.messageId == MessageId.MSG_NONE) {
        break;
      }

      print("轮询消息ID: ${msg.messageId.name}");

      // 处理板卡状态消息
      if (msg.messageId == MessageId.MSG_BOARD_STATUS) {
        final state = msg.message.popByte();
        // 发布板卡状态事件
        eventbus.fire(BoardStatusEvent(BoardStatus.values[state]));
        // 如果状态为1，退出循环
        if (state == 1) {
          break;
        }
      }

      // 处理任务进度报告消息
      if (msg.messageId == MessageId.MSG_REPORT_PROGRESS) {
        final progress = TaskProgress(
            msg.message.popByte(), // 容器ID
            msg.message.popByte(), // 任务ID
            msg.message.popByte(), // 位置
            TaskState.values[msg.message.popByte()] // 任务状态
            );
        print(
            "进度: ${progress.containerId}-${progress.taskId}-${progress.pos}-${progress.state}");
        // 发布任务进度事件
        eventbus.fire(progress);
      }

      // 处理组件错误设置消息
      if (msg.messageId == MessageId.MSG_SET_ERROR) {
        final component = msg.message.popByte(); // 组件ID
        final fatal = msg.message.popByte() == 1; // 是否致命错误
        final l = msg.message.popShort(); // 错误内容长度
        final content = msg.message.popString(l); // 错误内容
        print("获取到报错: ${component}-$fatal-$content");
        // 发布组件错误事件
        eventbus.fire(SetComponentError(component, fatal, content));
      }

      // 处理错误清除消息
      if (msg.messageId == MessageId.MSG_CLR_ERROR) {
        final l = msg.message.popShort(); // 内容长度
        final content = msg.message.popString(l); // 清除内容
        // 发布错误清除事件
        eventbus.fire(ClearComponentError(content));
      }

      // 处理数据更新消息
      if (msg.messageId == MessageId.MSG_UPDATE_DATA) {
        final task = msg.message.popByte(); // 任务ID
        final data = msg.message.popLong(); // 数据
        // TODO: 待实现 - 发布数据更新事件到事件总线
      }
      // 处理调试日志消息
      else if (msg.messageId == MessageId.MSG_LOG) {
        final id = msg.message.popByte(); // 日志ID
        final l = msg.message.popShort(); // 日志内容长度
        final content = msg.message.popString(l); // 日志内容
        // 发布调试日志事件
        eventbus.fire(DebugLog(id, content));
      }
    }
    return true;
  }

  /// 标识是否为耗时操作
  /// 轮询协议不涉及耗时操作
  @override
  bool isTimeConsuming() {
    return false;
  }

  /// 设置处理超时时间
  /// 返回0表示使用默认超时时间
  @override
  int setProcessTimeout() {
    return 0;
  }

  /// 设置请求标识
  /// 返回轮询请求的标识符
  @override
  RequestId setRequestId() {
    return RequestId.REQ_POLL;
  }
}
